package com.nanhai.buddhist.college.module.system.service.rolegroup;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nanhai.buddhist.college.framework.common.pojo.PageResult;
import com.nanhai.buddhist.college.framework.common.util.collection.CollectionUtils;
import com.nanhai.buddhist.college.module.system.controller.admin.rolegroup.vo.RoleGroupCreateReqVO;
import com.nanhai.buddhist.college.module.system.controller.admin.rolegroup.vo.RoleGroupExportReqVO;
import com.nanhai.buddhist.college.module.system.controller.admin.rolegroup.vo.RoleGroupPageReqVO;
import com.nanhai.buddhist.college.module.system.controller.admin.rolegroup.vo.RoleGroupRespVO;
import com.nanhai.buddhist.college.module.system.controller.admin.rolegroup.vo.RoleGroupUpdateReqVO;
import com.nanhai.buddhist.college.module.system.convert.rolegroup.RoleGroupConvert;
import com.nanhai.buddhist.college.module.system.dal.dataobject.rolegroup.RoleGroupDO;
import com.nanhai.buddhist.college.module.system.dal.dataobject.rolegroup.RoleGroupUserDO;
import com.nanhai.buddhist.college.module.system.dal.dataobject.user.AdminUserDO;
import com.nanhai.buddhist.college.module.system.dal.mysql.rolegroup.RoleGroupMapper;
import com.nanhai.buddhist.college.module.system.dal.mysql.rolegroup.RoleGroupUserMapper;
import com.nanhai.buddhist.college.module.system.dal.mysql.user.AdminUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.nanhai.buddhist.college.module.system.enums.ErrorCodeConstants.ROLE_GROUP_NOT_EXISTS;
import static com.nanhai.buddhist.college.module.system.enums.ErrorCodeConstants.ROLE_GROUP_USER_EXISTS;

/**
 * 群组管理 Service 实现类
 *
 * @author 南海佛学院
 */
@Service
@Validated
public class RoleGroupServiceImpl implements RoleGroupService {

    @Resource
    private RoleGroupMapper roleGroupMapper;

    @Resource
    private RoleGroupUserMapper roleGroupUserMapper;

    @Resource
    private RoleGroupUserService roleGroupUserService;


    @Resource
    private AdminUserMapper adminUserMapper;

    @Override
    @Transactional
    public Long createRoleGroup(RoleGroupCreateReqVO createReqVO) {
        // 插入
        RoleGroupDO roleGroup = RoleGroupConvert.INSTANCE.convert(createReqVO);

        roleGroup.setRoleIds(createReqVO.getRoleList());
        roleGroupMapper.insert(roleGroup);


        if (CollectionUtils.isNotEmpty(createReqVO.getUserIds())) {

            List<RoleGroupUserDO> collect = createReqVO.getUserIds().stream().map(s -> RoleGroupUserDO.builder().systemRoleGroupId(roleGroup.getId())
                    .userId(s).build()).collect(Collectors.toList());
            roleGroupUserMapper.insertBatch(collect);
        }
        // 返回
        return roleGroup.getId();
    }

    @Override
    public void updateRoleGroup(RoleGroupUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateRoleGroupExists(updateReqVO.getId());
        // 更新
        RoleGroupDO updateObj = RoleGroupConvert.INSTANCE.convert(updateReqVO);

        updateObj.setRoleIds(updateReqVO.getRoleList());
        roleGroupMapper.updateById(updateObj);

        List<RoleGroupUserDO> roleGroupUserDOS = roleGroupUserMapper.selectList(RoleGroupUserDO::getSystemRoleGroupId, updateReqVO.getId());
        if (CollectionUtils.isNotEmpty(roleGroupUserDOS)) {
            roleGroupUserMapper.deleteBatchIds(CollectionUtils.convertSet(roleGroupUserDOS, RoleGroupUserDO::getId));
        }

        if (CollectionUtils.isNotEmpty(updateReqVO.getUserIds())) {
            List<RoleGroupUserDO> collect = updateReqVO.getUserIds().stream().map(s -> RoleGroupUserDO.builder().systemRoleGroupId(updateReqVO.getId())
                    .userId(s).build()).collect(Collectors.toList());
            roleGroupUserMapper.insertBatch(collect);
        }
    }

    @Override
    public void deleteRoleGroup(Long id) {
        Long count = adminUserMapper.selectCount(AdminUserDO::getRoleGroupId, id);

        if (count > 0) {
            throw exception(ROLE_GROUP_USER_EXISTS);
        }
        // 校验存在
        this.validateRoleGroupExists(id);
        // 删除
        roleGroupMapper.deleteById(id);
        roleGroupUserMapper.delete(new LambdaQueryWrapper<RoleGroupUserDO>().eq(RoleGroupUserDO::getSystemRoleGroupId, id));


    }

    private void validateRoleGroupExists(Long id) {
        if (roleGroupMapper.selectById(id) == null) {
            throw exception(ROLE_GROUP_NOT_EXISTS);
        }
    }

    @Override
    public RoleGroupDO getRoleGroup(Long id) {
        return roleGroupMapper.selectById(id);
    }

    @Override
    public List<RoleGroupDO> getRoleGroupList(Collection<Long> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : roleGroupMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<RoleGroupDO> getRoleGroupPage(RoleGroupPageReqVO pageReqVO) {
        return roleGroupMapper.selectPage(pageReqVO);
    }

    @Override
    public List<RoleGroupDO> getRoleGroupList(RoleGroupExportReqVO exportReqVO) {
        return roleGroupMapper.selectList(exportReqVO);
    }

    @Override
    public RoleGroupRespVO convertRoleGroupRespVO(RoleGroupDO roleGroupDO) {
        RoleGroupRespVO convert = RoleGroupConvert.INSTANCE.convert(roleGroupDO);
        List<RoleGroupUserDO> roleGroupUserListBysystemRoleGroupId = roleGroupUserService.getRoleGroupUserListBysystemRoleGroupId(roleGroupDO.getId());
        Set<String> collect = CollectionUtils.convertSet(roleGroupUserListBysystemRoleGroupId, RoleGroupUserDO::getUserId);
        convert.setUserIds(collect);
//        convert.setRoleList(roleGroupDO.getRoleList());
        return convert;
    }


}
